package com.sample.wanandroidx.basic

import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleOwner
import androidx.viewbinding.ViewBinding
import com.classic.common.MultipleStatusView
import com.hjq.bar.OnTitleBarListener
import com.hjq.bar.TitleBar
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.impl.ConfirmPopupView

import com.sample.library.IView
import com.sample.library.ext.ActivityViewBindingInflater
import com.sample.library.ext.ProxyClickListener
import com.sample.library.ext.removeEscapeCharacter
import com.sample.library.ext.startActivity
import com.sample.library.util.CommonUtil
import com.sample.library.util.KeyBoardUtil
import com.sample.library.util.ToastUtil
import com.sample.library.util.ViewUtil
import com.sample.library.util.ViewUtil.setOnProxyClickListener
import com.sample.wanandroidx.R
import com.sample.wanandroidx.app.App
import com.sample.wanandroidx.support.IUrls
import com.sample.wanandroidx.support.NetworkChangeReceiver
import com.sample.wanandroidx.support.OnNetworkChangeEvent
import com.sample.wanandroidx.support.OnRefreshTokenEvent
import com.sample.wanandroidx.ui.home.LoginActivity
import com.xiasuhuei321.loadingdialog.view.LoadingDialog
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

abstract class BaseActivity<VB : ViewBinding>(private val bindingInflater: ActivityViewBindingInflater<VB>) : AppCompatActivity(),
                                                                                                              OnTitleBarListener,
                                                                                                              IView, IUrls,
                                                                                                              ProxyClickListener {

    private var lastClickTime: Long = 0

    private var tipsDialog: ConfirmPopupView? = null

    /**
     * theme color
     */
    protected var mThemeColor: Int = R.color.colorPrimary

    /**
     * 网络状态变化的广播
     */
    protected var mNetworkChangeReceiver: NetworkChangeReceiver? = null

    /**
     * 初始化binding
     */

    protected lateinit var binding: VB

    /**
     * 加载提示
     */
    private var loadingDialog: LoadingDialog? = null

    /**
     * 多种状态的 View 的切换
     */
    protected var multipleStatusView: MultipleStatusView? = null

    /**
     * 标题栏
     */
    protected var titlebar: TitleBar? = null

    private var mHandler: Handler? = null

    protected fun getHandler(): Handler? = mHandler

    private var isTips = false;

    /**
     * 初始化 数据或视图
     */
    abstract fun initialization()

    /**
     * 绑定视图监听事件
     */
    open fun bindingListener(vararg views: View) = views.forEach { it.setOnProxyClickListener(this) }

    /**
     * 是否使用 加载视图
     */
    open var useLoadingView: Boolean = true

    /**
     * 是否使用 EventBus
     */
    open fun useEventBus(): Boolean = true

    /**
     * 是否需要显示网络提示 默认显示
     */
    open fun enableNetworkTip(): Boolean = true

    /**
     * 在主线程中执行
     */
    open fun post(runnable: () -> Unit) = getHandler()?.post(runnable)

    /**
     * 在主线程中延时执行
     */
    open fun postDelayed(delayMilli: Long, runnable: () -> Unit) = getHandler()?.postDelayed(runnable, delayMilli)

    open fun onRetry() {
        initialization()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
        super.onCreate(savedInstanceState)

        mHandler = Handler(Looper.getMainLooper())
        binding = bindingInflater.invoke(layoutInflater)

        setContentView(binding.root)

        val list: List<View> = ViewUtil.getAllChildViews(window.decorView)

        titlebar = list.find { it is TitleBar } as TitleBar?
        titlebar?.setOnTitleBarListener(this)

        setTitleStr(title.toString())

        multipleStatusView = list.find { it is MultipleStatusView } as MultipleStatusView?
        if (multipleStatusView == null) {
            if (window.decorView is MultipleStatusView) {
                multipleStatusView = window.decorView as MultipleStatusView
            }
        }
        //有了自动重试机制,只需要跳转至网络设置即可
        multipleStatusView?.setOnRetryClickListener {
            startActivity(Intent(android.provider.Settings.ACTION_SETTINGS))
        }
        showLoading()

        if (useEventBus()) {
            EventBus.getDefault().register(this)
        }
        // 注册网络变化广播
        val filter = IntentFilter()
        filter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
        mNetworkChangeReceiver = NetworkChangeReceiver()
        registerReceiver(mNetworkChangeReceiver, filter)
        initialization()
    }

    /**
     * 设置标题/可覆盖
     */
    protected fun setTitleStr(title: String?) {
        titlebar?.title = title?.removeEscapeCharacter()
    }

    /**
     * Network Change
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    open fun onNetworkChangeEvent(eventOn: OnNetworkChangeEvent) {
        checkNetwork(eventOn.isConnected)
    }

    //登录提示
    @Subscribe(threadMode = ThreadMode.MAIN)
    open fun onRefreshTokenEvent(event: OnRefreshTokenEvent) {
        if (event.loginAction) {
            onRetry()
        } else {
            if (App.instance().getCurrentVisibleActivity() == this) {
                if (tipsDialog == null) {
                    tipsDialog = XPopup.Builder(this).asConfirm("请先登录", null) {
                        startActivity<LoginActivity>("index" to 1)
                    }
                    tipsDialog?.show()
                } else {
                    if (!tipsDialog!!.isShow) {
                        tipsDialog?.show()
                    }
                }
            }
        }
    }

    private fun checkNetwork(isConnected: Boolean) {
        if (enableNetworkTip()) {
            if (isConnected) {
                if (App.instance().getCurrentVisibleActivity() == this) {
                    //ToastUtil.show("网络已恢复")
                }
            } else {
                ToastUtil.show("网络已断开") //此处http请求失败会提示
            }
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        if (ev?.action == MotionEvent.ACTION_UP) {
            val v = currentFocus
            // 如果不是落在EditText区域，则需要关闭输入法
            if (KeyBoardUtil.isHideKeyboard(v, ev)) {
                KeyBoardUtil.hideKeyBoard(this, v)
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    override fun showLoadingDialog(resId: Int) {
        showLoadingDialog(getString(resId))
    }

    override fun updateLoadingDialog(progress: String) {
        post {
            loadingDialog?.setLoadingText(progress)
        }
    }

    override fun showLoadingDialog(desc: String) {
        dismissLoadingDialog()
        loadingDialog = LoadingDialog(this).setLoadingText(desc)
        loadingDialog?.show()
    }

    protected fun useNightMode(isNight: Boolean) {
        if (isNight) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
        }
        recreate()
    }

    override fun dismissLoadingDialog() {
        loadingDialog?.close()
    }

    override fun onPause() {
        if (mNetworkChangeReceiver != null) {
            unregisterReceiver(mNetworkChangeReceiver)
            mNetworkChangeReceiver = null
        }
        super.onPause()
    }

    override fun onDestroy() {
        dismissLoadingDialog()
        CommonUtil.fixInputMethodManagerLeak(this)
        if (useEventBus()) {
            EventBus.getDefault().unregister(this)
        }
        mHandler?.removeCallbacksAndMessages(null)
        mHandler = null
        super.onDestroy()
    }

    override fun withContext(): FragmentActivity {
        return this
    }

    override fun onLeftClick(v: View?) {
        finish()
    }

    override fun onTitleClick(v: View?) {
    }

    override fun onRightClick(v: View?) {
    }

    override fun showContent() {
        if (useLoadingView) multipleStatusView?.showContent()
    }

    override fun showEmpty() {
        multipleStatusView?.showEmpty()
    }

    override fun showError() {
        if (useLoadingView) multipleStatusView?.showError()
        dismissLoadingDialog()
    }

    override fun showLoading() {
        if (useLoadingView) multipleStatusView?.showLoading()
    }

    override fun closePage() {
        finish()
    }

    override fun showNoNetwork() {
        if (useLoadingView) multipleStatusView?.showNoNetwork()
        dismissLoadingDialog()
    }

    override fun <T : View> findViewWithId(id: Int): T {
        return binding.root.findViewById(id)
    }

    override fun getLifecycleOwner(): LifecycleOwner {
        return this
    }

    /**
     * @param eventId 事件ID
     */
    override fun onEvent(eventId: Int) {

    }

    override fun invoke(v: View) {

    }

    protected fun backPress() {
        if (lastClickTime <= 0) {
            lastClickTime = System.currentTimeMillis()
        } else {
            val currentClickTime = System.currentTimeMillis()
            if (currentClickTime - lastClickTime < 1000) {
                super.onBackPressed()
            } else {
                lastClickTime = currentClickTime
            }
        }
    }

}